package com.zxk.util;

import com.zxk.constant.ParamConstants;
import com.zxk.entity.FindPicResult;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.text.DecimalFormat;

/**
 * opencv
 *
 * @author: 舟小亢
 * @date: 2023-08-13 20:01
 */
public class OpencvUtil {

    private static Logger LOG = LoggerFactory.getLogger(OpencvUtil.class);

    private static DecimalFormat DF = new DecimalFormat("#.##");

    public static FindPicResult find(String bigImg, String smallImg) {
        return find(bigImg, smallImg, ParamConstants.SIMILARITY);
    }

    /**
     * opencv 图片匹配算法
     *
     * @param bigImg   大图
     * @param smallImg 小图
     * @param minSim   最小匹配度
     * @return
     */
    public static FindPicResult find(String bigImg, String smallImg, double minSim) {
        if (minSim > 1 || minSim < 0) {
            minSim = 0;
        }
        FindPicResult findPicResult = new FindPicResult();

        // 1.加载图像
        // 待匹配图片
        Mat src = Imgcodecs.imread(bigImg);
        // 获取匹配模板
        Mat template = Imgcodecs.imread(smallImg);

        // 2.进行模板匹配
        // 创建一个输出图像
        Mat outputImage = new Mat(src.rows(), src.cols(), src.type());
        Imgproc.matchTemplate(src, template, outputImage, Imgproc.TM_CCOEFF_NORMED);

        // 3.获取匹配结果,查找最大匹配值
        Core.MinMaxLocResult result = Core.minMaxLoc(outputImage);
        Point matchLoc = result.maxLoc;
        //匹配度
        double similarity = result.maxVal;
        //小图大大图中的x坐标
        int x = (int) matchLoc.x;
        //小图大大图中的y坐标
        int y = (int) matchLoc.y;

        // 4.返回合适匹配度的结果
        if (similarity >= minSim) {
            LOG.info("opencv 匹配{}结果 [x:{} y:{} sim:{} ]", smallImg.substring(smallImg.lastIndexOf(File.separator) + 1), x, y, DF.format(similarity));
            findPicResult.setPicX(x);
            findPicResult.setPicY(y);
            findPicResult.setFinded(true);
            findPicResult.setSimilarity(similarity);
        }

        return findPicResult;
    }

}
